package com.homer.gps.track.helper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.widget.Toast;

import com.homer.gps.track.R;

public class ImageHelper {

	public static String SUFFIX_JPG = ".jpg";
	public static String SUFFIX_PNG = ".png";
	public static String SUFFIX_JSON = ".json";
	public static String SUFFIX_MEASURED = "_toolbox.jpg";

	public ImageHelper() {
	} 

	public ImageHelper getInstance() {
		return new ImageHelper();
	} 


	public static boolean checkExistingImageNamesInDirectory(final String imageName, String targetDirectory) {

		File directory = new File(targetDirectory);

		File[] imageFiles = directory.listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String filename) {
				if (filename.equals(imageName + SUFFIX_JPG)) {
					return true;
				}
				return false;
			}
		});

		if (imageFiles.length > 0)
			return Boolean.TRUE;

		return Boolean.FALSE;
	} 

	public static String getImageNameNoExtensionFromImagePath(String imagePath) {
		int imageNameStartPos = imagePath.lastIndexOf(File.separator) + 1;
		int imageNameEndPos;
		if (imagePath.toLowerCase().endsWith(SUFFIX_PNG)) {
			imageNameEndPos = imagePath.toLowerCase().indexOf(SUFFIX_PNG);
		} else {
			imageNameEndPos = imagePath.toLowerCase().indexOf(SUFFIX_JPG);
		}
		String name = imagePath.substring(imageNameStartPos, imageNameEndPos);
		return name;
	} 

	public static boolean rotateImage(String path) {
		boolean success = false;
		try {
			Bitmap bitmap = decodeBitmap(path, 3);

			if (bitmap != null) {
				ExifInterface exif = new ExifInterface(path);
				int o = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
				if (o != ExifInterface.ORIENTATION_NORMAL) {
					Matrix m = new Matrix();
					switch (o) {
					case ExifInterface.ORIENTATION_ROTATE_90:
						m.postRotate(90);
						break;
					case ExifInterface.ORIENTATION_ROTATE_180:
						m.postRotate(180);
						break;
					case ExifInterface.ORIENTATION_ROTATE_270:
						m.postRotate(270);
						break;
					}
					bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
				}

				exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_NORMAL));

				FileOutputStream fos = new FileOutputStream(new File(path));
				bitmap.compress(CompressFormat.JPEG, 90, fos);
				fos.flush();
				fos.close();
				bitmap.recycle();

				exif.saveAttributes();

				success = true;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return success;
	}

	public static Bitmap decodeBitmap(String photoPath) {
		return decodeBitmap(photoPath, 1);
	}

	private static Bitmap decodeBitmap(String photoPath, int inSampleSize) {
		try {
			Options op = new Options();
			op.inSampleSize = inSampleSize;
			return BitmapFactory.decodeFile(photoPath, op);
		} catch (OutOfMemoryError e) {
			System.gc();
			return decodeBitmapDownsized(photoPath, 800);
		}
	}

	private static Bitmap decodeBitmapDownsized(String photoPath, int downSize) {
		try {
			return downsizeImage(photoPath, downSize);
		} catch (OutOfMemoryError  e) {
			System.gc();
			return decodeBitmapDownsized(photoPath, downSize - 100);
		}
	}

	public static Bitmap mergeBitmap(Bitmap background, Bitmap foreground) {
		Canvas c = new Canvas(background);
		c.drawBitmap(foreground, background.getWidth()/2.0f - foreground.getWidth()/2.0f, background.getHeight()/2.0f - foreground.getHeight()/2.0f, null);
		return background;
	}

	private static Bitmap downsizeImage(String photoPath, int size) throws OutOfMemoryError{


		BitmapFactory.Options o = new BitmapFactory.Options();
		o.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(photoPath, o);


		int scale=1;
		int max = o.outWidth > o.outHeight? o.outWidth : o.outHeight;
		while(max/scale >= size)
			scale*=2;


		BitmapFactory.Options o2 = new BitmapFactory.Options();
		o2.inSampleSize=scale;

		return BitmapFactory.decodeFile(photoPath, o2);
	}

	public static Bitmap decodeFile(File f) {
		Bitmap b = null;
		try {

			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inJustDecodeBounds = true;

			FileInputStream fis = new FileInputStream(f);
			BitmapFactory.decodeStream(fis, null, o);
			fis.close();

			int scale = 4;


			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize = scale;
			fis = new FileInputStream(f);
			b = BitmapFactory.decodeStream(fis, null, o2);

			fis.close();
		} catch (IOException e) {
		}
		return b;
	}
}
